/* 
* Copyright (C) 2005, 2006 Liu Di <liudidi@gmail.com> 
*
* Copyright (C) 2007 Wei Lian <lianwei3@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "header.h"
#include "channel.h"
#include "mainwindow.h"
#include "mylistitem.h"
#include "config.h"
#include "mylabel.h"
#include "menubar.h"
#include "pageplay.h"
#include "record.h"
#include "tabwidget.h"
#include "utils.h"

Channel::Channel (QWidget * parent, const char *name, WFlags f):
QListView (parent, name, f),
mainwindow (static_cast < MainWindow * >(parent))
{
    //listview
    addColumn (tr ("Name"));
/*  addColumn(tr("Status"));
    addColumn(tr("Type"));
    addColumn(tr("Kbps"));
    addColumn(tr("Users"));
    addColumn(tr("Vists"));
    addColumn(tr("QualityS"));
    addColumn(tr("QualityC"));
    addColumn(tr("StarFrom"));
    addColumn(tr("URL"));
    addColumn(tr("Description"));*/
    setRootIsDecorated (TRUE);

    connect (this, SIGNAL (doubleClicked (QListViewItem *)), this,
	     SLOT (onListItemClicked (QListViewItem *)));
    connect (this, SIGNAL (returnPressed (QListViewItem *)), this,
	     SLOT (onListItemClicked (QListViewItem *)));
    connect (this,
	     SIGNAL (rightButtonClicked
		     (QListViewItem *, const QPoint &, int)), this,
	     SLOT (onRightButtonClicked (QListViewItem *, const QPoint &, int)));
    connect (this, SIGNAL (onItem (QListViewItem *)), this, SLOT (onMouseMoved (QListViewItem *)));

    //popup
    popup = new MyLabel (this);
    //buffer
    bufchannel = new QBuffer ();
    ///open bufchannel
    if (!bufchannel->open (IO_ReadWrite)) {
	perror ("cannot create the buffer");
	return;
    }
    ////
    wget = new QProcess (this);
    wget->setCommunication (QProcess::Stdout);
    connect (wget, SIGNAL (processExited ()), this, SLOT (onWgetExit ()));
    connect (wget, SIGNAL (readyReadStdout ()), this, SLOT (wgetStdout ()));

}


Channel::~Channel ()
{
    ///close bufchannel
    bufchannel->close ();
    delete bufchannel;
}


///-------------------------------------------------------
void
Channel::onListItemClicked (QListViewItem *)
{
    if (static_cast < MyHBox * >(mainwindow->tabwidget->currentPage ())
	->pagetype == "play")
	static_cast < PagePlay * >(mainwindow->tabwidget->currentPage ())
	    ->onButtonLaunchClicked ();
    else
	static_cast < Record * >(mainwindow->tabwidget->currentPage ())
	    ->buttonrecord->setOn (true);
}



void
Channel::onButtonChannelToggled (bool t)
{
    if (t) {
	///reset buffer pointer to 0
	bufchannel->reset ();
	///launch wget
	wget->clearArguments ();
	wget->addArgument ("wget");
	wget->addArgument (mainwindow->vboxconfig->editchannelurl->text ());
	wget->addArgument ("-O");
	wget->addArgument ("-");
	wget->start ();
    } else {
	///terminate wget
	char str[256];
	strcpy (str, wget->arguments ().join (" ").ascii ());
	killProcess (str, wget->processIdentifier (), wget->processIdentifier () + 10);
	///reset color for button channel
	mainwindow->buttonchannel->setPaletteForegroundColor (Qt::black);
    }
}


void
Channel::wgetStdout ()
{
    bufchannel->writeBlock (wget->readStdout ());
    int done = bufchannel->at ();
    ///use button channel forground color to illuminate progress
    int period = 178805;
    int num = (done / period) % 2 ?
	255 - (256 * done / period) % 256 : (256 * done / period) % 256;
    ///
    mainwindow->buttonchannel->setPaletteForegroundColor (QColor (0, num, 0));

}


void
Channel::onWgetExit ()
{
    ///reset button channel and reset its color
    mainwindow->buttonchannel->setOn (false);

    ///toggle channel sorting
    toggleChannelSort ();
    ///

    ///reset buffer pointer to 0
    bufchannel->reset ();
    QDomDocument doc;
    doc.setContent (bufchannel);
    ////

    QListViewItem *groupitem = 0;
    MyListItem *item = 0;

    updateOpenState ();
    clear ();

    for (int i = 0; i < N_COLUMNS; i++)
	Max[i] = 1;
    static const char node_name[][20] = { "name", "status", "stream_type", "kbps", "user_count",
	"visit_count", "qs", "qc", "start_from", "sop_address",
	"description"
    };


    ///group
    for (QDomNode group = doc.documentElement ().firstChild ();
	 !group.isNull (); group = group.nextSibling ()) {
	if (group.isElement () && group.nodeName () == "group") {
	    groupitem = new QListViewItem (this, groupitem);
	    groupitem->setText (0, group.firstChild ().nodeValue ());
	    ///channel
	    for (QDomNode channelnode = group.firstChild ();
		 !channelnode.isNull (); channelnode = channelnode.nextSibling ()) {
		if (channelnode.isElement ()
		    && channelnode.nodeName () == "channel") {
		    ///element
		    item = new MyListItem (groupitem, item);
		    for (QDomNode namenode = channelnode.firstChild ();
			 !namenode.isNull (); namenode = namenode.nextSibling ()) {
			for (int i = 0; i < N_COLUMNS; i++) {
			    if (namenode.nodeName () == "sop_address")
				item->setText (URL_COLUMN,
					       namenode.firstChild ().firstChild ().nodeValue ());
			    else if (namenode.nodeName () == node_name[i])
				item->setText (i, namenode.firstChild ().nodeValue ());
			}
		    }

		    ///filtering out channel
		    if (channelnode.toElement ().attribute ("type").toInt () == 1)
			item->state |= 2;
		    ///disable null channel
		    else if (item->text (URL_COLUMN) == "null")
			item->state |= 1;
		    else {
			static const int num[] = { USER_COLUMN, VISIT_COLUMN, QS_COLUMN,
			    QC_COLUMN, KBPS_COLUMN
			};
			for (int i = 0; i < 5; i++)
			    Max[num[i]] =
				item->text (num[i]).toInt () >
				Max[num[i]] ? item->text (num[i]).toInt () : Max[num[i]];

		    }
		}
	    }
	    ///group
	}
    }

    ///toggle null channel
    toggleNullChannel ();

    ////switch color
    switchChannelColor (mainwindow->menubar->color_column);

    ///set open
    QListViewItem *group = firstChild ();
    int minNum = int (childCount ()) < int (stateopen.count ())
	? int (childCount ()) : int (stateopen.count ());
    for (int i = 0; i < minNum; ++i) {
	if (*(stateopen.at (i)) == 1)
	    group->setOpen (TRUE);
	group = group->nextSibling ();
    }

}


void
Channel::onRightButtonClicked (QListViewItem * item, const QPoint & pos, int)
{
    if (item)
	if (item->depth () == 1) {
	    popup->move (pos);
	    popup->
		setText
		("<table border=0 cellspacing=0 cellpadding=0><tr><td>" +
		 item->text (NAME_COLUMN) +
		 "</td></tr></table><hr>"
		 "<table border=0 cellspacing=0 cellpadding=0>"
		 "<tr><td>Users: " + item->text (USER_COLUMN) +
		 "</td><td>Visitors: " + item->text (VISIT_COLUMN) +
		 "</td></tr>" "<tr><td>QualityC: " +
		 item->text (QC_COLUMN) + "</td><td>QualityS: " +
		 item->text (6) + "</td></tr>" "<tr><td>MediaType: " +
		 item->text (STREAM_COLUMN) + "</td><td>KBps: " +
		 item->text (KBPS_COLUMN) +
		 "</td></tr>" "<tr><td>StartFrom: " +
		 item->text (START_COLUMN) + "</td></tr></table><br>" +
		 item->text (DESCRIPTION_COLUMN));
	    popup->adjustSize ();
	    popup->show ();
	}
}


void
Channel::onMouseMoved (QListViewItem *)
{
    popup->hide ();
}


void
Channel::mouseMoveEvent (QMouseEvent * e)
{
    QPoint p (e->pos ());
    QRect pr (rect ());
    pr.setWidth (pr.width () -
		 verticalScrollBar ()->width () * verticalScrollBar ()->isVisible ());
    pr.setHeight (pr.height () -
		  horizontalScrollBar ()->height () * horizontalScrollBar ()->isVisible ());
    if (!pr.contains (p)) {
	popup->hide ();
    }
}


void
Channel::toggleChannelSort ()
{
    if (!mainwindow->menubar->menu_config->isItemChecked (CHANNEL_SORT))
	setSortColumn (-1);
    else
	setSortColumn (0);
}


void
Channel::toggleNullChannel ()
{
    bool t = mainwindow->menubar->menu_config->isItemChecked (NULL_CHANNEL);

    QListViewItem *group = firstChild ();
    while (group) {
	QListViewItem *child = group->firstChild ();
	int count = 0;
	while (child) {
	    switch (((MyListItem *) child)->state) {
	    case 0:
	    case 2:
		count++;
		break;
	    case 1:
		child->setEnabled (FALSE);
		if (t) {
		    child->setVisible (TRUE);
		    count++;
		} else
		    child->setVisible (FALSE);
		break;
	    case 3:
		child->setEnabled (FALSE);
		child->setVisible (FALSE);
	    }
	    child = child->nextSibling ();
	}
	if (count == 0)
	    group->setVisible (FALSE);
	else
	    group->setVisible (TRUE);
	///iterate to next group
	group = group->nextSibling ();
    }
}


void
Channel::switchChannelColor (int column)
{
    QListViewItem *group = firstChild ();
    while (group) {
	QListViewItem *child = group->firstChild ();
	while (child) {
	    if (child->isEnabled ()) {
		int level = int (child->text (column).toInt () * (255. / Max[column]));

		level = level < 0 ? 0 : level;
		level = level > 255 ? 255 : level;

		((MyListItem *) child)->fcolor.setHsv (255 - level, 255, 125);
		child->repaint ();
	    }
	    child = child->nextSibling ();
	}
	group = group->nextSibling ();
    }
}


void
Channel::updateOpenState ()
{
    int minNum = int (childCount ()) < int (stateopen.count ())
	? int (childCount ()) : int (stateopen.count ());
    QListViewItem *item = firstChild ();

    for (int i = 0; i < minNum; ++i) {
	if (item->isOpen ())
	    *(stateopen.at (i)) = 1;
	else
	    *(stateopen.at (i)) = 0;

	item = item->nextSibling ();
    }
    ///if childCount > stateopen.count
    if (minNum < childCount ()) {
	while (item) {
	    if (item->isOpen ())
		stateopen.append (1);
	    else
		stateopen.append (0);

	    item = item->nextSibling ();
	}
    }
}


bool
Channel::SopMatch (QString & channelurl, QString & channelname, QString & channeltype)
{
    channelname = "sop";
    channeltype = "wmv";

    int startpos = channelurl.find (mainwindow->vboxconfig->editchannelheader->text ());
    ///not a valid URL
    if (startpos == -1)
	return false;
    ///normalize URL
    channelurl = channelurl.mid (startpos);
    channelurl = channelurl.mid (0, channelurl.find (" "));

    ///traversal the channel list to find the 1st match
    QListViewItem *item, *childitem;
    item = firstChild ();
    while (item) {
	childitem = item->firstChild ();
	while (childitem) {
	    if (channelurl == childitem->text (URL_COLUMN)) {
		channelname = childitem->text (NAME_COLUMN);
		channeltype = childitem->text (STREAM_COLUMN);
		goto FINISHED;
	    }
	    childitem = childitem->nextSibling ();
	}
	item = item->nextSibling ();
    }
  FINISHED:

    return true;
}
